package com.yanqu.road.server.gameplayer.module.activity.snowgarden;

import com.yanqu.road.dao.impl.activity.snowgarden.UserSnowGardenVisitRecordDaoImpl;
import com.yanqu.road.dao.impl.activity.snowgarden.UserSnowGardenVisitRelationDaoImpl;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.snowgarden.*;
import com.yanqu.road.entity.activity.snowgarden.config.*;
import com.yanqu.road.entity.config.goods.MallInfo;
import com.yanqu.road.entity.enums.activity.snowgarden.*;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eLogMoneyType;
import com.yanqu.road.entity.enums.eShopType;
import com.yanqu.road.entity.enums.eSystemId;
import com.yanqu.road.entity.log.LogSnowGardenBuild;
import com.yanqu.road.entity.log.LogSnowGardenDraw;
import com.yanqu.road.entity.log.LogSnowGardenVisit;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.union.cross.CrossUnionMember;
import com.yanqu.road.logic.helper.ActivityHelper;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.pb.activity.SnowGardenProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.base.GeneralModule;
import com.yanqu.road.server.gameplayer.module.player.CurrencyModule;
import com.yanqu.road.server.manger.ServerListMgr;
import com.yanqu.road.server.manger.activity.ActivityMgr;
import com.yanqu.road.server.manger.activity.snowgarden.SnowGardenMgr;
import com.yanqu.road.server.manger.config.SystemOpenMgr;
import com.yanqu.road.server.manger.log.AutoLogMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.union.CrossUnionMgr;
import com.yanqu.road.server.pb.SnowGardenPb;
import com.yanqu.road.server.protocol.*;
import com.yanqu.road.sync.message.SyncResponse;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;

public class SnowGardenModule extends GeneralModule {

//    private Map<Integer, SnowGardenVisitorRecordData> snowGardenVisitorRecordData;

    private Map<Long, UserSnowGardenVisitRelation> relationMap = new ConcurrentHashMap<>();
    private List<UserSnowGardenVisitRecord> helpOtherRecordList = new ArrayList<>();
    private List<UserSnowGardenVisitRecord> helpMeRecordList = new ArrayList<>();

    private List<UserSnowGardenVisitRecord> needInsertHelpRecordList = new ArrayList<>();
    // 缓存好友列表,等待从其他游戏拉过来聚合,每次请求列表和发送后都会清空
    private Map<Long, SnowGardenVisitUserData> cacheVisitUserData = new ConcurrentHashMap<>();

    private Random random = new Random();

    public SnowGardenModule(GamePlayer player) {
        super(player);
    }

    @Override
    public boolean loadData() {
        ActivityInfo activityInfo = SnowGardenMgr.getActivityInfo();
        if (ActivityMgr.activityInShowTime(activityInfo)) {
            int period = SnowGardenMgr.calcNowPeriod();

            Map<Long, UserSnowGardenVisitRelation> tempRelationMap = new UserSnowGardenVisitRelationDaoImpl().getUserSnowGardenVisitRelationMap(activityInfo.getActivityId(), getUserId());
            List<UserSnowGardenVisitRecord> tempHelpMeList = new ArrayList<>();
            List<UserSnowGardenVisitRecord> tempHelpOtherList = new ArrayList<>();
            List<UserSnowGardenVisitRecord> tempRecordList = new UserSnowGardenVisitRecordDaoImpl().getUserSnowGardenVisitRecord(activityInfo.getActivityId(), getUserId());
            List<UserSnowGardenVisitRecord> cacheVisitRecordDataList = SnowGardenMgr.popCacheVisitRecordData(activityInfo.getActivityId(), getUserId());
            if (cacheVisitRecordDataList != null) {
                tempRecordList.addAll(cacheVisitRecordDataList);
            }

            {//重新统计协助次数
                for (UserSnowGardenVisitRecord visitRecord : tempRecordList) {
                    UserSnowGardenVisitRelation visitRelation = tempRelationMap.get(visitRecord.getTargetUserId());
                    if (visitRelation == null) {
                        visitRelation = new UserSnowGardenVisitRelation(visitRecord.getActivityId(), getUserId(), visitRecord.getTargetUserId());
                        tempRelationMap.put(visitRelation.getTargetUserId(), visitRelation);
                    }

                    if (visitRecord.getPeriod() == 1) {
                        if (visitRecord.getVisitType() == eSnowGardenVisitType.VISIT_TYPE_VISITED_ME.getType()) {
                            visitRelation.setTempHelpMeCount(visitRelation.getTempHelpMeCount() + 1);
                            if (visitRecord.getVisitTime() > visitRelation.getTempHelpMeTime()) {
                                visitRelation.setTempHelpMeTime(visitRecord.getVisitTime());
                            }
                        } else {
                            visitRelation.setTempHelpHerCount(visitRelation.getTempHelpHerCount() + 1);
                            if (visitRecord.getVisitTime() > visitRelation.getTempHelpHerTime()) {
                                visitRelation.setTempHelpHerTime(visitRecord.getVisitTime());
                            }
                        }
                    } else {
                        if (visitRecord.getVisitType() == eSnowGardenVisitType.VISIT_TYPE_VISITED_ME.getType()) {
                            visitRelation.setTempHelpMeCount2(visitRelation.getTempHelpMeCount2() + 1);
                            if (visitRecord.getVisitTime() > visitRelation.getTempHelpMeTime()) {
                                visitRelation.setTempHelpMeTime(visitRecord.getVisitTime());
                            }
                        } else {
                            visitRelation.setTempHelpHerCount2(visitRelation.getTempHelpHerCount2() + 1);
                            if (visitRecord.getVisitTime() > visitRelation.getTempHelpHerTime()) {
                                visitRelation.setTempHelpHerTime(visitRecord.getVisitTime());
                            }
                        }
                    }

                    if (visitRecord.getPeriod() != period) {
                        continue;
                    }

                    if (visitRecord.getVisitType() == eSnowGardenVisitType.VISIT_TYPE_VISITED_ME.getType()) {
                        tempHelpMeList.add(visitRecord);
                    } else {
                        tempHelpOtherList.add(visitRecord);
                    }
                }

                for (UserSnowGardenVisitRelation visitRelation : tempRelationMap.values()) {
                    visitRelation.setHelpMeCount(visitRelation.getTempHelpMeCount());
                    visitRelation.setHelpHerCount(visitRelation.getTempHelpHerCount());
                    visitRelation.setHelpMeCount2(visitRelation.getTempHelpMeCount2());
                    visitRelation.setTempHelpHerCount2(visitRelation.getTempHelpHerCount2());
                }
            }

            relationMap = tempRelationMap;
            helpMeRecordList = tempHelpMeList;
            helpOtherRecordList = tempHelpOtherList;
        }
        return true;
    }

    @Override
    public boolean afterLoadData() {
        return true;
    }

    @Override
    public boolean saveData() {
        List<UserSnowGardenVisitRecord> saveRecordList = new ArrayList<>();
        synchronized (needInsertHelpRecordList) {
            saveRecordList.addAll(needInsertHelpRecordList);
            needInsertHelpRecordList.clear();
        }
        if (!saveRecordList.isEmpty()) {
            for (UserSnowGardenVisitRecord visitRecord : saveRecordList) {
                if (visitRecord.isInsertOption()) {
                    new UserSnowGardenVisitRecordDaoImpl().add(visitRecord);
                } else if (visitRecord.isUpdateOption()) {
                    new UserSnowGardenVisitRecordDaoImpl().update(visitRecord);
                }
            }
        }

        List<UserSnowGardenVisitRelation> saveRelationList = new ArrayList<>();
        synchronized (relationMap) {
            saveRelationList.addAll(relationMap.values());
        }
        for (UserSnowGardenVisitRelation visitRelation : saveRelationList) {
            if (visitRelation.isInsertOption()) {
                new UserSnowGardenVisitRelationDaoImpl().add(visitRelation);
            } else if (visitRelation.isUpdateOption()) {
                new UserSnowGardenVisitRelationDaoImpl().update(visitRelation);
            }
        }

        return true;
    }

    @Override
    public void afterLogin() {
        refreshData();
    }


    public void refreshData() {
        initUserData();
        syncConfig();
        syncUserData();
        SnowGardenConfig config = SnowGardenMgr.getSnowGardenConfig();
        if (config != null) {
            SnowGardenUserData snowGardenUserData = SnowGardenMgr.getSnowGardenUserDataOnlyGet(config.getActivityInfo().getActivityId(), getUserId());
            if (snowGardenUserData != null) {
                player.notifyListener(eGamePlayerEventType.SnowGardenScoreRank.getValue(), snowGardenUserData.getScore());
                player.notifyListener(eGamePlayerEventType.SnowGardenSecondScoreRank.getValue(), snowGardenUserData.getSecondScore());
                player.notifyListener(eGamePlayerEventType.SnowGardenBuildingLevel.getValue(), snowGardenUserData.getBuildingLevel());
                player.notifyListener(eGamePlayerEventType.SnowGardenVisitCount.getValue(), snowGardenUserData.getInvitedNum());
            }
        }
    }

    // 同步配置
    public void syncConfig() {
        SnowGardenConfig config = SnowGardenMgr.getSnowGardenConfig();
        if (config != null) {
            SnowGardenProto.SnowGardenSyncConfigRespMsg.Builder builder = SnowGardenPb.parseSnowGardenSyncConfigRespMsg(config, player.getLanguage());
            player.sendPacket(ClientProtocol.U_SNOW_GARDEN_CONFIG_SYNC, builder);
        }
    }

    public void syncUserData() {
        SnowGardenConfig config = SnowGardenMgr.getSnowGardenConfig();
        if (config == null) {
            return;
        }
        SnowGardenUserData userData = SnowGardenMgr.getSnowGardenUserDataOnlyGet(config.getActivityInfo().getActivityId(), getUserId());
        if (config != null && userData != null) {
            SnowGardenProto.SnowGardenSyncUserDataRespMsg.Builder builder = SnowGardenProto.SnowGardenSyncUserDataRespMsg.newBuilder();
            int nowPeriod = SnowGardenMgr.calcNowPeriod();
            // 阶段期间或结束不修改阶段状态
            SnowGardenMgr.changePeriod(nowPeriod, userData);
            SnowGardenProto.SnowGardenUserDataMsg.Builder userBuilder = SnowGardenPb.parseSnowGardenUserData(userData);
            builder.setUserData(userBuilder);
            player.sendPacket(ClientProtocol.U_SNOW_GARDEN_GET_USER_DATA, builder);
        }
    }

    // 初始化角色数据
    public synchronized void initUserData() {
        // 没解锁
        if (!SystemOpenMgr.systemOpen(player, eSystemId.SnowGarden.getValue())) {
            return;
        }
        SnowGardenConfig config = SnowGardenMgr.getSnowGardenConfig();
        // 没活动
        if (config == null || !ActivityMgr.activityInShowTime(config.getActivityInfo())) {
            return;
        }

        SnowGardenMgr.getSnowGardenUserDataNewIfNull(config.getActivityInfo().getActivityId(), getUserId());
    }

    // 系统解锁
    public void initSystem() {
        // 身份解锁
        if (!SystemOpenMgr.systemOpen(player, eSystemId.SnowGarden.getValue())) {
            return;
        }
        refreshData();
    }

    /**
     * 进入界面获取数据
     */
    public int getData() {
        SnowGardenConfig config = SnowGardenMgr.getSnowGardenConfig();
        if (config == null || !ActivityMgr.activityInTime(config.getActivityInfo())) {
            return GameErrorCode.E_ACTIVITY_HAD_END;
        }
        SnowGardenUserData userData = SnowGardenMgr.getSnowGardenUserDataOnlyGet(config.getActivityInfo().getActivityId(), getUserId());
        if (userData == null) {
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }
        int nowPeriod = SnowGardenMgr.calcNowPeriod();
        SnowGardenMgr.changePeriod(nowPeriod, userData);
        SnowGardenProto.SnowGardenGetDataRespMsg.Builder builder = SnowGardenProto.SnowGardenGetDataRespMsg.newBuilder();
        builder.setRet(0);
        SnowGardenProto.SnowGardenUserDataMsg.Builder userBuilder = SnowGardenPb.parseSnowGardenUserData(userData);
        builder.setUserData(userBuilder);
        player.sendPacket(ClientProtocol.U_SNOW_GARDEN_GET_DATA, builder);
        return 0;
    }

    /**
     * 冰雪游园会投掷
     *
     * @param period 投掷阶段
     * @param times  投掷次数
     * @param isSkip 是否跳过
     * @return
     */
    public int draw(int period, int times, boolean isSkip, List<Integer> number) {
        SnowGardenConfig snowGardenConfig = SnowGardenMgr.getSnowGardenConfig();
        if (snowGardenConfig == null || !ActivityMgr.activityInTime(snowGardenConfig.getActivityInfo())) {
            return GameErrorCode.E_ACTIVITY_HAD_END;
        }

        int channelId = ServerListMgr.getChannelId(GameServer.getInstance().getServerId());
        if (channelId != 666) { //只有内网能用调试参数
            if (!number.isEmpty()) {
                log.error("冰雪,不是内网渠道也传调试参数,userId:{}", player.getUserId());
                return GameErrorCode.E_ERROR_DATA;
            }
        }

        int nowPeriod = SnowGardenMgr.calcNowPeriod();
        if (nowPeriod != period) {
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }
        if (period != eSnowGardenPeriodType.UPGRADE_PERIOD.getType() && period != eSnowGardenPeriodType.VISITOR_PERIOD.getType()) {
            // 既不在上述阶段，认定活动结束
            return GameErrorCode.E_ACTIVITY_HAD_END;
        }

        // 准备数据
        SnowGardenUserData snowGardenUserData = SnowGardenMgr.getSnowGardenUserDataOnlyGet(snowGardenConfig.getActivityInfo().getActivityId(), getUserId());
        int combNum = snowGardenUserData.getCombList().size();
        if (combNum > 0){
            return GameErrorCode.E_SNOW_GARDEN_COMB_UNCHECK;
        }

        // 随机结果
        List<Integer> randomResultList = new ArrayList<>();
        // 邀请角色ID列表
        List<Integer> invitedIdList = new ArrayList<>();
        // 事件邀请角色ID列表
        List<Integer> combInvitedIdList = new ArrayList<>();
        // 触发的事件
        List<SnowGardenCombTriggerData> combList = new ArrayList<>();
        // 奖励积分数量
        int awardScore = 0;
        int randomNum = 0;
        // 事件奖励
        Property property = new Property();
        // 骰子随机奖励
        List<String> randomAward = new ArrayList<>();
        // 记录前进步数
        int sumStep = 0;
        // 记录初始位置(客户端需求)
        int recordIndex = snowGardenUserData.getIndexNum();

        // 一圈的长度
        int mapStepNumb = snowGardenConfig.getMapSize();

        if (period != eSnowGardenPeriodType.UPGRADE_PERIOD.getType() &&
                period != eSnowGardenPeriodType.VISITOR_PERIOD.getType()) {
            return GameErrorCode.E_ACTIVITY_HAD_END;
        }

        // 扣除道具
        boolean costRet = costItem(snowGardenConfig, period, times);
        if (!costRet) {
            return GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
        }

        // 皮肤倍率+ 阶段倍率
        BigDecimal radio = SnowGardenMgr.calcSkinRadio(snowGardenUserData.getSkinList(), snowGardenUserData.getIndexData(), period);

        // 随机种子
//        Random random = new Random();
        // 如果传了指定列表，那就按指定列表的来
        if (number.size() > 0) {
            times = number.size();
        }
        synchronized (snowGardenUserData) {
// 遍历roll点
            while (times > 0) {
                // 阶段1走到这个地块上升级建筑
                if (period == eSnowGardenPeriodType.UPGRADE_PERIOD.getType()) {
                    randomNum = SnowGardenMgr.randomOneStep(SnowGardenMgr.rollNum, number, times, snowGardenUserData);
                    randomResultList.add(randomNum);
                    int nowIndex = snowGardenUserData.getIndexNum();
                    sumStep += randomNum;
                    int newIndex = nowIndex + randomNum;
                    if (newIndex > mapStepNumb) {
                        // 如果超过地图的长度则圈数+1，从1开始走
                        newIndex -= mapStepNumb;
                    }
                    snowGardenUserData.setIndexNum(newIndex);
                    int indexType = snowGardenConfig.getIndexType(newIndex);
                    int configScore = snowGardenConfig.getScoreByIndex(newIndex);
                    if (indexType == eSnowGardenMapType.LONG_PLOT.getType()) {
                        // 升级建筑
                        SnowGardenMapData mapData = snowGardenUserData.getIndexData().get(newIndex);
                        mapData.setLevel(mapData.getLevel() + 1);
                    }
                    awardScore += BigDecimal.valueOf(configScore).multiply(radio).setScale(0, RoundingMode.CEILING).intValue();
                } else {
                    // 二阶段邀请门客、美女
                    randomNum = SnowGardenMgr.randomOneStep(SnowGardenMgr.secondRollNum, number, times, snowGardenUserData);
                    randomResultList.add(randomNum);
                    int id = snowGardenConfig.randomVisitorConfigId();
                    int configScore = snowGardenConfig.getVisitorScore(id);
                    BigDecimal scoreWithRadio = BigDecimal.valueOf(configScore).multiply(radio).setScale(0, RoundingMode.CEILING); // CEILING模式用于实现向上取整
                    awardScore += scoreWithRadio.intValue();

                    List<Integer> invitedList = snowGardenUserData.getInvitedIdList();
                    if (invitedList.size() >= snowGardenConfig.getVisitCountMax()) {
                        invitedList.remove(0); // 移除头个
                    }
                    invitedList.add(snowGardenConfig.getVisitorId(id));
                    invitedIdList.add(snowGardenConfig.getVisitorId(id));
                    snowGardenUserData.setInvitedIdList(invitedList);
                }

                // 判断九格的三消
                List<Integer> resultList = snowGardenUserData.getResultList();
                SnowGardenResultCombData snowGardenResultCombData = SnowGardenMgr.calcResultComb(resultList, randomNum);
                int combId = 0;
                for (int combMapKey : snowGardenConfig.getSnowGardenCombConfig().keySet()) {
                    if (snowGardenConfig.checkComb(combMapKey, nowPeriod, randomNum)) {
                        combId = combMapKey;
                        break;
                    }
                }

                // 开始触发事件列表
                SnowGardenCombTriggerData triggerData = new SnowGardenCombTriggerData();
                int combCount = snowGardenResultCombData.getCombCount();
                // 优化：（多次）奖励事件改为相同道具 x 次数,仅随机一次
                Property p = snowGardenConfig.getCombReward(combId);
                for (int i = 0; i < combCount; i++) {
                    triggerData.setCombId(combId);
                    int param = snowGardenConfig.getCombParam(combId);
                    if (combId == eSnowGardenCombType.FIRST_PERIOD_COMB_ONE.getId()) {
//                    param = (int)Math.ceil(param * radio);
                        param = BigDecimal.valueOf(param).multiply(radio).setScale(0, RoundingMode.CEILING).intValue();
                        awardScore += param;
                        triggerData.addParam(String.valueOf(param));
                    } else if (combId == eSnowGardenCombType.FIRST_PERIOD_COMB_TWO.getId()) {
                        int newIndex = snowGardenUserData.getIndexNum();
                        sumStep += param;
                        List<Integer> recordIndexList = new ArrayList<>();
                        for (int j = 1; j <= param; j++) {
                            newIndex++;
                            if (newIndex > mapStepNumb) {
                                // 如果超过地图的长度则圈数+1，从1开始走
                                newIndex -= mapStepNumb;
                            }
                            int indexType = snowGardenConfig.getIndexType(newIndex);
                            int configScore = snowGardenConfig.getScoreByIndex(newIndex);
                            awardScore += BigDecimal.valueOf(configScore).multiply(radio).setScale(0, RoundingMode.CEILING).intValue();
                            recordIndexList.add(newIndex);
                            Map<Integer, SnowGardenMapData> map = snowGardenUserData.getIndexData();
                            if (indexType == eSnowGardenMapType.LONG_PLOT.getType()) {
                                // 升级建筑
                                SnowGardenMapData combMap = map.get(newIndex);
                                combMap.setLevel(combMap.getLevel() + 1);
                            }
                        }
                        snowGardenUserData.setIndexNum(newIndex);
                        String newParam = StringUtils.listToString(recordIndexList, ";");
                        triggerData.addParam(String.valueOf(param));
                        triggerData.addSkipParam(newParam);
                    } else if (combId == eSnowGardenCombType.FIRST_PERIOD_COMB_THREE.getId()) {
                        Property buildingProperty = new Property(snowGardenConfig.getBuildItemId(), param);
                        property.addProperty(buildingProperty);
                        triggerData.addParam(String.valueOf(param));
                    } else if (combId == eSnowGardenCombType.FIRST_PERIOD_COMB_FOUR.getId()) {
                        int newIndex = snowGardenUserData.getIndexNum();
                        Map<Integer, SnowGardenMapData> newMap = snowGardenUserData.getIndexData();
                        SnowGardenMapData combMap = newMap.get(newIndex);
                        combMap.setLevel(combMap.getLevel() + param);
                        int configScore = snowGardenConfig.getScoreByIndex(newIndex);
//                    awardScore += (int)Math.ceil(statueConfig.getScore() * radio);
                        awardScore += BigDecimal.valueOf(configScore * param).multiply(radio).setScale(0, RoundingMode.CEILING).intValue();
                        triggerData.addParam(String.valueOf(param));
                        if (isSkip) {
                            triggerData.addSkipParam(String.valueOf(newIndex));
                        }
                    } else if (combId == eSnowGardenCombType.FIRST_PERIOD_COMB_FIVE.getId()) {
                        // 随机商会好友(除自己) 还要排除没开活动的
                        String unionUid = player.getUserInfo().getUnionUid();
                        CrossUnionMember unionMember = SnowGardenMgr.randomOneUnionMember(getUserId(), unionUid);
                        // 未加入商会则无拜访列表
                        if (unionMember == null) {
//                        param = (int)Math.ceil(snowGardenConfig.getNoUnionComb4Score() * radio);
                            param = BigDecimal.valueOf(snowGardenConfig.getNoUnionComb4Score()).multiply(radio).setScale(0, RoundingMode.CEILING).intValue();
                            awardScore += param;
                            triggerData.addParam(String.valueOf(param));
                        } else {
                            // 随机地块
                            int randomIndex = SnowGardenMgr.initIndexId();
                            String addParam = String.format("%d_%d_%d", unionMember.getUserId(), unionMember.getServerId(), randomIndex);
                            triggerData.addParam(addParam);
                            if (isSkip) { // 跳过直接发到跨服
                                int randomStatue = snowGardenConfig.getSnowGardenMapConfig().get(randomIndex).getStatueId();
                                int randomScore = snowGardenConfig.getStatueScore(randomStatue);
//                            awardScore += (int) Math.ceil(randomScore * param * radio);
                                awardScore += BigDecimal.valueOf(randomScore).multiply(BigDecimal.valueOf(param)).multiply(radio).setScale(0, RoundingMode.CEILING).intValue();
                                triggerData.addSkipParam(String.format("%d_%d_%s", randomIndex, param, unionMember.getUserBaseInfo().getNickName()));
                                visit(unionMember.getServerId(), unionMember.getUserId(), eSnowGardenRequestVisitType.BUILDING.getType(), randomIndex);
                            } else {
                                SnowGardenCombTriggerData recordData = new SnowGardenCombTriggerData();
                                recordData.setCombId(combId);
                                recordData.addParam(addParam);
                                snowGardenUserData.addCombTriggerData(recordData);
                            }
                        }
                    } else if (combId == eSnowGardenCombType.FIRST_PERIOD_COMB_SIX.getId()) {
                        property.addProperty(p);
                        triggerData.addParam(PropertyHelper.parsePropertyToString(p));
                    } else if (combId == eSnowGardenCombType.SECOND_PERIOD_COMB_ONE.getId()) {
//                    int paramScore = (int)Math.ceil(param * radio);
                        int paramScore = BigDecimal.valueOf(param).multiply(radio).setScale(0, BigDecimal.ROUND_CEILING).intValue();
                        awardScore += paramScore;
                        triggerData.addParam(String.valueOf(paramScore));
                    } else if (combId == eSnowGardenCombType.SECOND_PERIOD_COMB_TWO.getId()) {
                        Property combOneAward = new Property(snowGardenConfig.getVisitItemId(), param);
                        property.addProperty(combOneAward);
                        triggerData.addParam(String.valueOf(param));
                    } else if (combId == eSnowGardenCombType.SECOND_PERIOD_COMB_THREE.getId()) {
                        int randomId = SnowGardenMgr.randomOneMoreVisitor();
                        int randomVisitorId = snowGardenConfig.getVisitorId(randomId);
                        int repeatedScore = snowGardenConfig.getVisitorScore(randomId);
//                    awardScore += (int)Math.ceil(repeatedScore * param * radio);
                        awardScore += BigDecimal.valueOf(repeatedScore).multiply(BigDecimal.valueOf(param)).multiply(radio).setScale(0, BigDecimal.ROUND_CEILING).intValue();
                        List<Integer> invitedList = snowGardenUserData.getInvitedIdList();
                        if (invitedList.size() >= snowGardenConfig.getVisitCountMax()) {
                            invitedList.remove(0); // 移除头个
                        }
                        invitedList.add(randomVisitorId);
                        combInvitedIdList.add(randomVisitorId);
                        triggerData.addParam(String.valueOf(randomVisitorId));
                    } else if (combId == eSnowGardenCombType.SECOND_PERIOD_COMB_FOUR.getId()) {
                        // 随机商会好友(除自己)
                        String unionUid = player.getUserInfo().getUnionUid();
                        CrossUnionMember unionMember = SnowGardenMgr.randomOneUnionMember(getUserId(), unionUid);
                        // 未加入商会则无拜访列表
                        if (unionMember == null) {
//                        param = (int)Math.ceil(snowGardenConfig.getNoUnionComb10Score()* radio);
                            param = BigDecimal.valueOf(snowGardenConfig.getNoUnionComb10Score()).multiply(radio).setScale(0, BigDecimal.ROUND_CEILING).intValue();
                            awardScore += param;
                            triggerData.addParam(String.valueOf(param));
                        } else {
                            // 随机游客
                            int randomVisitor = SnowGardenMgr.initVisitorId();
                            int randomId = snowGardenConfig.getVisitorId(randomVisitor);
                            String addParam = String.format("%d_%d_%d", unionMember.getUserId(), unionMember.getServerId(), randomVisitor);
                            triggerData.addParam(addParam);
                            if (isSkip) {
//                            int randomScore = (int) Math.ceil(snowGardenVisitorConfig.get(randomVisitor).getScore() * radio);
                                int visitorScore = snowGardenConfig.getVisitorScore(randomVisitor);
                                int randomScore = BigDecimal.valueOf(visitorScore).multiply(radio).intValue();
                                awardScore += randomScore;
                                triggerData.addSkipParam(String.format("%d_%d_%s", randomId, randomScore, unionMember.getUserBaseInfo().getNickName()));
                                visit(unionMember.getServerId(), unionMember.getUserId(), eSnowGardenRequestVisitType.INVITED.getType(), randomVisitor);
                            } else {
                                SnowGardenCombTriggerData recordData = new SnowGardenCombTriggerData();
                                recordData.setCombId(combId);
                                recordData.addParam(addParam);
                                snowGardenUserData.addCombTriggerData(recordData);
                            }
                        }
                    } else if (combId == eSnowGardenCombType.SECOND_PERIOD_COMB_FIVE.getId()) {
                        property.addProperty(p);
                        // 这里要重设返回值
                        triggerData.addParam(PropertyHelper.parsePropertyToString(p));
                    }
                }
                combList.add(triggerData);


                if (combCount > 0) {
                    snowGardenUserData.setGuarantee(SnowGardenMgr.randomGuarantee(nowPeriod));
                } else if (snowGardenUserData.getDice().size() == 0) {
                    // 需要当模板走完之后才开始正常的保底计数
                    snowGardenUserData.setGuarantee(snowGardenUserData.getGuarantee() - 1);
                }
                snowGardenUserData.setResultList(snowGardenResultCombData.getResultList());
                Property randomRollAward = SnowGardenMgr.getRollReward(period);
                property.addProperty(randomRollAward);
                randomAward.add(PropertyHelper.parsePropertyToString(randomRollAward));
                times--;
            }

            snowGardenUserData.setLoopNum(snowGardenUserData.getLoopNum() + randomResultList.size());
            snowGardenUserData.addScore(nowPeriod, awardScore);
            snowGardenUserData.setUpdateOption();

            player.getModule(CurrencyModule.class).addCurrency(property, eLogMoneyType.SnowGarden, eLogMoneyType.SnowGardenDrawAward);
            snowGardenUserData.addInviteNum(invitedIdList.size() + combInvitedIdList.size());
        }

        // 更新排行榜、发送事件
        updateRank(snowGardenUserData, nowPeriod);
        int buildingSumLevel = snowGardenUserData.getBuildingLevel();
        sendNotify(snowGardenUserData);

        // 触发日志
        LogSnowGardenDraw drawLog = new LogSnowGardenDraw(snowGardenConfig.getActivityInfo().getActivityId(), getUserId(), snowGardenUserData.getPeriodScore(nowPeriod), buildingSumLevel, radio.doubleValue(), randomResultList.toString(), new Date());
        AutoLogMgr.add(drawLog);
        if (period == eSnowGardenPeriodType.UPGRADE_PERIOD.getType()) { // 一阶段记录建筑日志
            for (SnowGardenCombTriggerData c : combList) {
                LogSnowGardenBuild log = new LogSnowGardenBuild(snowGardenConfig.getActivityInfo().getActivityId(), getUserId(), 1, sumStep, snowGardenUserData.getIndexNum(), c.getCombId(), c.getParam(), awardScore, new Date());
                AutoLogMgr.add(log);
            }
        } else if (period == eSnowGardenPeriodType.VISITOR_PERIOD.getType()) { // 二阶段记录邀请日志
            for (SnowGardenCombTriggerData c : combList) {
                LogSnowGardenVisit log = new LogSnowGardenVisit(snowGardenConfig.getActivityInfo().getActivityId(), getUserId(), 1, c.getCombId(), c.getParam(), awardScore, new Date());
                AutoLogMgr.add(log);
            }
        }

        // 返回数据
        SnowGardenProto.SnowGardenDrawRespMsg.Builder builder = SnowGardenProto.SnowGardenDrawRespMsg.newBuilder();
        builder.setRet(0);
        builder.addAllResultList(randomResultList);
        for (SnowGardenCombTriggerData combData : combList) {
            builder.addCombList(SnowGardenPb.parseSnowGardenCombDataMsg(combData));
        }
        SnowGardenProto.SnowGardenUserDataMsg.Builder userBuilder = SnowGardenPb.parseSnowGardenUserData(snowGardenUserData);
        builder.setUserData(userBuilder);
        builder.addAllInvitedIdList(invitedIdList);
        builder.setAwardScore(awardScore);
        builder.setOldIndex(recordIndex);
        builder.addAllRandomAward(randomAward);
        player.sendPacket(ClientProtocol.U_SNOW_GARDEN_DRAW, builder);

        return 0;
    }

    private boolean costItem(SnowGardenConfig config, int period, int times) {
        int consumeId = 0;
        int costCount = 0;
        if(period == eSnowGardenPeriodType.UPGRADE_PERIOD.getType()){
            consumeId = config.getBuildItemId();
            costCount = config.getBuildItemCost() * times;
        } else if (period == eSnowGardenPeriodType.VISITOR_PERIOD.getType()){
            consumeId = config.getVisitItemId();
            costCount = config.getVisitItemCost() * times;
        }
        Property consume = new Property(consumeId, costCount);
        return player.getModule(CurrencyModule.class).removeCurrency(consume, eLogMoneyType.SnowGarden, eLogMoneyType.SnowGardenDrawCost);
    }

    // 更新排行榜
    public void updateRank(SnowGardenUserData snowGardenUserData, int period) {
        // 发送事件，触发监听
        if (period == eSnowGardenPeriodType.UPGRADE_PERIOD.getType()) {
            player.notifyListener(eGamePlayerEventType.SnowGardenScoreRank.getValue(), snowGardenUserData.getScore());
        } else if (period == eSnowGardenPeriodType.VISITOR_PERIOD.getType()) {
            player.notifyListener(eGamePlayerEventType.SnowGardenSecondScoreRank.getValue(), snowGardenUserData.getSecondScore());
        }
    }

    // 发送事件
    private void sendNotify(SnowGardenUserData snowGardenUserData) {
        int period = snowGardenUserData.getPeriod();
        if (period == eSnowGardenPeriodType.UPGRADE_PERIOD.getType()) {
            player.notifyListener(eGamePlayerEventType.SnowGardenBuildingLevel.getValue(), snowGardenUserData.getBuildingLevel());
        } else if (period == eSnowGardenPeriodType.VISITOR_PERIOD.getType()) {
            player.notifyListener(eGamePlayerEventType.SnowGardenVisitCount.getValue(), snowGardenUserData.getInvitedNum());
        }
    }


    /**
     * 修改玩家服装
     *
     * @param suitId 服装id
     * @return ret
     */
    public int changeSuit(int suitId) {
        SnowGardenConfig config = SnowGardenMgr.getSnowGardenConfig();
        if (config == null || !ActivityMgr.activityInTime(config.getActivityInfo())) {
            return GameErrorCode.E_ACTIVITY_HAD_END;
        }
        // 准备数据
        SnowGardenUserData snowGardenUserData = SnowGardenMgr.getSnowGardenUserDataOnlyGet(config.getActivityInfo().getActivityId(), getUserId());
        Map<Integer, SnowGardenSkinData> skinMap = snowGardenUserData.getSkinList();
        if (!skinMap.containsKey(suitId)) {
            return GameErrorCode.E_SNOW_GARDEN_SKIN_NOT_FOUND;
        }
        SnowGardenSkinData skinData = skinMap.get(suitId);
        long now = System.currentTimeMillis();
        if (skinData.getLimitTime() != -1 && now >= skinData.getLimitTime()) {
            return GameErrorCode.E_SNOW_GARDEN_SKIN_OVER_TIME;
        }
        skinData.setUnlock(true);
        snowGardenUserData.setSuit(suitId);

        SnowGardenProto.SnowGardenSuitRespMsg.Builder builder = SnowGardenProto.SnowGardenSuitRespMsg.newBuilder();
        builder.setRet(0);
        player.sendPacket(ClientProtocol.U_SNOW_GARDEN_CHANGE_SUIT, builder);

        return 0;
    }

    /**
     * 请求访问列表
     *
     * @return
     */
    public int getVisitList() {
        SnowGardenConfig config = SnowGardenMgr.getSnowGardenConfig();
        if (config == null) {
            return GameErrorCode.E_ACTIVITY_NO_FOUND;
        }

        String unionUid = player.getUserInfo().getUnionUid();
        // 未加入商会则无拜访列表
        if (StringUtils.isNullOrEmpty(unionUid)) {
            return GameErrorCode.E_UNION_NO_JOIN_UNION;
        }

        SnowGardenUserData snowGardenUserData = SnowGardenMgr.getSnowGardenUserDataOnlyGet(config.getActivityInfo().getActivityId(), getUserId());
        if (snowGardenUserData == null) {
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }

//        if (!cacheVisitUserData.isEmpty()) {
//            return GameErrorCode.E_SNOW_WAIT_VISIT_LIST_BACK;
//        }

        cacheVisitUserData.clear();

        Map<Long, List<Long>> needFromOtherServerUserMap = new HashMap<>();

        int activityId = snowGardenUserData.getActivityId();
        Map<Long, CrossUnionMember> unionMemberMap = CrossUnionMgr.getUnionMemberMap(unionUid);
        for (CrossUnionMember unionMember : unionMemberMap.values()) {
            if (unionMember.getUserId() == getUserId()) {
                continue;
            }

            //防止导活动没覆盖到
            if (!config.getActivityInfo().getServerIdList().contains(unionMember.getServerId())) {
                continue;
            }

            SnowGardenVisitUserData data = new SnowGardenVisitUserData();
            data.setUserId(unionMember.getUserId());
            data.setUserData(unionMember.getUserBaseInfo());
            data.setWaitBack(true);

            UserSnowGardenVisitRelation targetRelation = getTargetRelation(unionMember.getUserId());
            if (targetRelation != null) {
                if (snowGardenUserData.getPeriod() == 1) {
                    data.setHelpTimes(targetRelation.getHelpMeCount());
                } else {
                    data.setHelpTimes(targetRelation.getHelpMeCount2());
                }
            }

            if (unionMember.getServerId() == GameServer.getInstance().getServerId()) {
                SnowGardenUserData targetUserSnowUserData = SnowGardenMgr.getSnowGardenUserDataOnlyGet(activityId, unionMember.getUserId());
                if (targetUserSnowUserData != null) {
                    data.setScore(targetUserSnowUserData.getPeriodScore(targetUserSnowUserData.getPeriod()));
                    data.setBuildingLevel(targetUserSnowUserData.getBuildingLevel());
                }
            } else {
                data.setWaitBack(false);
                List<Long> userIds = needFromOtherServerUserMap.get(unionMember.getServerId());
                if (userIds == null) {
                    userIds = new ArrayList<>();
                    needFromOtherServerUserMap.put(unionMember.getServerId(), userIds);
                }
                userIds.add(unionMember.getUserId());
            }

            cacheVisitUserData.put(data.getUserId(), data);
        }

        if (needFromOtherServerUserMap.isEmpty()) {
            List<SnowGardenProto.SnowGardenVisitUserDataMsg> visitUserDataMsgList = parseCacheVisitUserDataList();

            SnowGardenProto.SnowGardenVisitListRespMsg.Builder builder = SnowGardenProto.SnowGardenVisitListRespMsg.newBuilder();
            builder.setRet(0);
            builder.setPage(1);
            builder.setPageSize(visitUserDataMsgList.size());
            builder.addAllVisitUserList(visitUserDataMsgList);
            player.sendPacket(ClientProtocol.U_SNOW_GARDEN_GET_VISITOR_LIST, builder);
        } else {
            for (Map.Entry<Long, List<Long>> entry : needFromOtherServerUserMap.entrySet()) {
                long serverId = entry.getKey();
                List<Long> userIds = entry.getValue();

                SnowGardenProto.SnowGetOtherGameUserDataMsg.Builder reqMsg = SnowGardenProto.SnowGetOtherGameUserDataMsg.newBuilder();
                reqMsg.setActivityId(activityId);
                reqMsg.addAllTargetUserId(userIds);

                SnowGardenProto.SnowGardenVisitUserDataFromOtherGameMsg.Builder resp = SnowGardenProto.SnowGardenVisitUserDataFromOtherGameMsg.newBuilder();

                CompletableFuture<SyncResponse> future = GamePlayerMgr.sendToGameServer(serverId, GameProtocol.S_SNOW_GET_USER_VISIT_DATA_FROM_GAME, player.getUserId(), reqMsg, resp);
                future.thenAccept((SyncResponse syncResponse) -> {
                    if (syncResponse.getErrorCode() != 0) {
                        cacheVisitUserData.clear();
                        log.error("getVisitList error, userId:{}, serverId:{}, errorCode:{}", player.getUserId(), serverId, syncResponse.getErrorCode());
                        return;
                    }

                    for (SnowGardenProto.SnowGardenVisitUserDataFromOtherGameTemp userDataFromOtherGameTemp : resp.getVisitUserListList()) {
                        SnowGardenVisitUserData data = cacheVisitUserData.get(userDataFromOtherGameTemp.getUserId());
                        if (data == null) {
                            continue;
                        }
                        data.setScore(userDataFromOtherGameTemp.getScore());
                        data.setBuildingLevel(userDataFromOtherGameTemp.getBuildingLevel());
                        data.setWaitBack(true);
                    }

                    boolean isAllBack = true;
                    for (SnowGardenVisitUserData visitUserData : cacheVisitUserData.values()) {
                        if (!visitUserData.isWaitBack()) {
                            isAllBack = false;
                            break;
                        }
                    }

                    if (isAllBack) {

                        List<SnowGardenProto.SnowGardenVisitUserDataMsg> visitUserDataMsgList = parseCacheVisitUserDataList();

                        SnowGardenProto.SnowGardenVisitListRespMsg.Builder builder = SnowGardenProto.SnowGardenVisitListRespMsg.newBuilder();
                        builder.setRet(0);
                        builder.setPage(1);
                        builder.setPageSize(visitUserDataMsgList.size());
                        builder.addAllVisitUserList(visitUserDataMsgList);
                        player.sendPacket(ClientProtocol.U_SNOW_GARDEN_GET_VISITOR_LIST, builder);
                    }
                });
            }
        }

        return 0;
    }

    private List<SnowGardenProto.SnowGardenVisitUserDataMsg> parseCacheVisitUserDataList() {
        List<SnowGardenProto.SnowGardenVisitUserDataMsg> visitUserDataMsgList = new ArrayList<>();
        for (SnowGardenVisitUserData visitUserData : cacheVisitUserData.values()) {
            visitUserDataMsgList.add(SnowGardenPb.parseSnowGardenVisitUserData(visitUserData).build());
        }
        cacheVisitUserData.clear();
        visitUserDataMsgList.sort((o1, o2) -> {
            int compare = Integer.compare(o2.getBuildingLevel(), o1.getBuildingLevel());
            if (compare == 0) {
                compare = Long.compare(o2.getScore(), o1.getScore());
            }
            return compare;
        });
        return visitUserDataMsgList;
    }

    /**
     * @param targetServerId
     * @param visitUserId
     * @param visitType
     * @param targetObjectId 跳过时随机的id
     * @return
     */
    public int visit(long targetServerId, long visitUserId, int visitType, int targetObjectId) {
        SnowGardenConfig config = SnowGardenMgr.getSnowGardenConfig();
        if (config == null || !ActivityMgr.activityInTime(config.getActivityInfo())) {
            return GameErrorCode.E_ACTIVITY_HAD_END;
        }

        SnowGardenUserData snowGardenUserData = SnowGardenMgr.getSnowGardenUserDataOnlyGet(config.getActivityInfo().getActivityId(), getUserId());
        if (snowGardenUserData == null) {
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }

        int activityId = snowGardenUserData.getActivityId();

        if (visitType == 0) {
            // 非指定上述类型拜访则不需要记录拜访数据,下发数据后返回
            SnowGardenProto.SnowGardenToCrossVisitReqMsg.Builder msg = SnowGardenProto.SnowGardenToCrossVisitReqMsg.newBuilder();
            msg.setActivityId(activityId);
            msg.setUserId(getUserId());
            msg.setUserServerId(GameServer.getInstance().getServerId());
            msg.setTargetUserId(visitUserId);
            msg.setTargetServerId(targetServerId);
            msg.setVisitType(visitType);
            msg.setVisitParam("");
            msg.setRecordTime(0);
            // 将对方信息推送至跨服
            player.sendPacket(Protocol.C_SNOW_GARDEN_VISITED, msg);
            return 0;
        }

        if (targetObjectId == -1) {//客户端主动请求的协助,要判断有没有存这个东西
            // 移除存储的拜访事件数据
            SnowGardenCombTriggerData triggerData = popCombTriggerData(snowGardenUserData, visitType, visitUserId);
            if (triggerData == null) {
                return GameErrorCode.E_SNOW_GARDEN_VISIT_TYPE_ERR;
            }
            List<Long> list = StringUtils.stringToLongList(triggerData.getParam(), "_");
            Long paramUserId = list.get(0);
            Long paramServerId = list.get(1);
            if (paramUserId != visitUserId || targetServerId != paramServerId) {
                return GameErrorCode.E_SNOW_GARDEN_VISIT_TARGET_USER_ERROR;
            }
        }

        int objectId = targetObjectId;
        String result;
        int param;
        int score = 0;
        int period = snowGardenUserData.getPeriod();
        BigDecimal skinRadio = SnowGardenMgr.calcSkinRadio(snowGardenUserData.getSkinList(), snowGardenUserData.getIndexData(), period);
        if (visitType == eSnowGardenRequestVisitType.BUILDING.getType()) {
            if (objectId == -1) {
                objectId = SnowGardenMgr.initIndexId();
            }
            param = SnowGardenMgr.getSnowGardenConfig().getSnowGardenCombConfig().get(eSnowGardenCombType.FIRST_PERIOD_COMB_FIVE.getId()).getParam();
            int statueId = SnowGardenMgr.getSnowGardenConfig().getSnowGardenMapConfig().get(objectId).getStatueId();
            int paramScore = SnowGardenMgr.getSnowGardenConfig().getSnowGardenStatueConfig().get(statueId).getScore() * param;
            score = BigDecimal.valueOf(paramScore).multiply(skinRadio).setScale(0, RoundingMode.CEILING).intValue();
            result = String.format("%d_%d_%d", objectId, param, score);
        } else if (visitType == eSnowGardenRequestVisitType.INVITED.getType()) {
            List<Integer> randomVisitorIdList;
            Map<Integer, SnowGardenVisitorConfig> snowGardenVisitorConfig = SnowGardenMgr.getSnowGardenConfig().getSnowGardenVisitorConfig();
            randomVisitorIdList = new ArrayList<>(snowGardenVisitorConfig.keySet());
            int id = targetObjectId;
            if (objectId == -1) {
                int randomIndex = random.nextInt(randomVisitorIdList.size());
                id = randomVisitorIdList.get(randomIndex);

            }
            objectId = snowGardenVisitorConfig.get(id).getVisitorId();

            param = SnowGardenMgr.getSnowGardenConfig().getSnowGardenCombConfig().get(eSnowGardenCombType.SECOND_PERIOD_COMB_FOUR.getId()).getParam();
            int paramScore = snowGardenVisitorConfig.get(id).getScore() * param;
            score = BigDecimal.valueOf(paramScore).multiply(skinRadio).setScale(0, RoundingMode.CEILING).intValue();
            result = String.format("%d_%d_%d", objectId, param, score);
        } else {
            return GameErrorCode.E_SNOW_GARDEN_VISIT_TYPE_ERR;
        }

        // 更新我的拜访列表
        UserSnowGardenVisitRecord visitRecord = addVisitRecord(activityId, visitUserId, eSnowGardenVisitType.VISIT_TYPE_MY_VISITED.getType(), objectId, score, true, DateHelper.getCurrentTime());

        // 更新我的奖励
        // 优化：一二阶段积分拆分
        snowGardenUserData.addScore(period, score);
        snowGardenUserData.setUpdateOption();
        updateRank(snowGardenUserData, period);
        // 同步一下自己的新数据给客户端
        syncUserData();

        // 将对方信息推送至跨服
        SnowGardenProto.SnowGardenToCrossVisitReqMsg.Builder msg = SnowGardenProto.SnowGardenToCrossVisitReqMsg.newBuilder();
        msg.setActivityId(activityId);
        msg.setUserId(getUserId());
        msg.setUserServerId(GameServer.getInstance().getServerId());
        msg.setTargetUserId(visitUserId);
        msg.setTargetServerId(targetServerId);
        msg.setVisitType(visitType);
        msg.setVisitParam(result);
        msg.setRecordTime(visitRecord.getVisitTime());
        player.sendPacket(Protocol.C_SNOW_GARDEN_VISITED, msg);

        return 0;
    }

    /**
     * 别人拜访我
     *
     * @param visitUserId
     * @param visitServerId
     * @param visitType
     * @param visitParam
     * @param targetUserId
     * @param targetServerId
     * @param recordTime
     * @return
     */
    public synchronized int crossVisit(long visitUserId, long visitServerId, int visitType, String visitParam, long targetUserId, long targetServerId, long recordTime) {
        initUserData();
        SnowGardenConfig config = SnowGardenMgr.getSnowGardenConfig();
        if (config == null) {
            return GameErrorCode.E_ACTIVITY_NOT_OPEN;
        }
        SnowGardenUserData visitUserData = SnowGardenMgr.getSnowGardenUserDataNewIfNull(config.getActivityInfo().getActivityId(), targetUserId);
        if (visitUserData == null) {
            return GameErrorCode.E_SYSTEM_NO_OPEN;
        }

        if (getUserId() != targetUserId) {
            return GameErrorCode.E_USER_NO_FOUND;
        }

        int activityId = visitUserData.getActivityId();
        UserBaseInfo userBase = UserMgr.getUserBaseInfo(targetUserId, targetServerId);
        if (userBase == null) {
            return GameErrorCode.E_USER_NO_FOUND;
        }
        int recordId;
        String result;
        int realAwardScore = 0;
        int period = 0;
        synchronized (visitUserData) {
            SnowGardenMgr.changePeriod(SnowGardenMgr.calcNowPeriod(), visitUserData);
            period = visitUserData.getPeriod();
            BigDecimal skinRadio = SnowGardenMgr.calcSkinRadio(visitUserData.getSkinList(), visitUserData.getIndexData(), period);
            if (visitType == eSnowGardenRequestVisitType.BUILDING.getType()) {
                // 升级建筑 参数  地块_升级等级_拜访者获得积分
                List<Integer> paramList = StringUtils.stringToIntegerList(visitParam, "_");
                recordId = paramList.get(0);
                int randomStatue = SnowGardenMgr.getSnowGardenConfig().getSnowGardenMapConfig().get(recordId).getStatueId();
                int oldLevel = visitUserData.getIndexData().get(recordId).getLevel();
                // 升级建筑 + 积分
                int newLevel = oldLevel + paramList.get(1);
                visitUserData.getIndexData().get(recordId).setLevel(newLevel);
                int paramScore = SnowGardenMgr.getSnowGardenConfig().getSnowGardenStatueConfig().get(randomStatue).getScore() * paramList.get(1);
                realAwardScore = BigDecimal.valueOf(paramScore).multiply(skinRadio).setScale(0, RoundingMode.CEILING).intValue();
                result = String.format("%d_%d_%d", recordId, newLevel, paramList.get(2));
            } else if (visitType == eSnowGardenRequestVisitType.INVITED.getType()) {
                // 邀请 参数  游客id_积分倍率_拜访者获得积分
                List<Integer> paramList = StringUtils.stringToIntegerList(visitParam, "_");
                recordId = paramList.get(0);
                visitUserData.addInviteNum(1);
                int paramScore = SnowGardenMgr.getVisitorScoreById(recordId) * paramList.get(1);
                realAwardScore = BigDecimal.valueOf(paramScore).multiply(skinRadio).setScale(0, RoundingMode.CEILING).intValue();
                visitUserData.getInvitedIdList().add(recordId);
                result = String.format("%d_%d", recordId, paramList.get(2));
            } else {
                // 非指定上述类型拜访则不需要记录拜访数据,下发数据后返回
                SnowGardenProto.SnowGardenToCrossVisitRespMsg.Builder builder = SnowGardenProto.SnowGardenToCrossVisitRespMsg.newBuilder();
                builder.setActivityId(activityId);
                builder.setRet(0);
                builder.setUserId(visitUserId);
                builder.setUserServerId(visitServerId);
                builder.setUserData(PlayerBasePb.parsePlayerBaseTempMsg(userBase));
                SnowGardenProto.VisitOtherSnowGardenTemp.Builder userBuilder = SnowGardenPb.parseVisitOtherSnowGardenTemp(visitUserData);
                builder.setUserActData(userBuilder);
                builder.setVisitResult("");
                builder.setVisitedUserId(targetUserId);
                builder.setRecordTime(recordTime);
                // 发到跨服
                player.sendPacket(CrossProtocol.C_SNOW_GARDEN_VISITED_RESP, builder);
                return 0;
            }
            visitUserData.addScore(period, realAwardScore);
            visitUserData.setUpdateOption();
        }


        // 更新我的奖励
        // 优化：一二阶段积分拆分
        updateRank(visitUserData, period);
        sendNotify(visitUserData);

        // 来访记录
        //更新我的来访列表
        addVisitRecord(activityId, visitUserId, eSnowGardenVisitType.VISIT_TYPE_VISITED_ME.getType(), recordId, realAwardScore, false, DateHelper.getCurrentTime());

        syncUserData();

        SnowGardenProto.SnowGardenToCrossVisitRespMsg.Builder builder = SnowGardenProto.SnowGardenToCrossVisitRespMsg.newBuilder();
        builder.setActivityId(activityId);
        builder.setRet(0);
        builder.setUserId(visitUserId);
        builder.setUserServerId(visitServerId);
        builder.setUserData(PlayerBasePb.parsePlayerBaseTempMsg(userBase));
        SnowGardenProto.VisitOtherSnowGardenTemp.Builder userBuilder = SnowGardenPb.parseVisitOtherSnowGardenTemp(visitUserData);
        builder.setUserActData(userBuilder);
        builder.setVisitResult(result);
        builder.setVisitedUserId(targetUserId);
        builder.setRecordTime(recordTime);
        // 发到跨服
        player.sendPacket(CrossProtocol.C_SNOW_GARDEN_VISITED_RESP, builder);
        return 0;
    }

    public UserSnowGardenVisitRecord addVisitRecord(int activityId, long targetUserId, int visitType, int objectId, int addScore, boolean needCrossBack, long visitTime) {
        int nowPeriod = SnowGardenMgr.calcNowPeriod();

        UserSnowGardenVisitRelation targetRelation = getTargetRelation(targetUserId);
        if (targetRelation == null) {
            synchronized (relationMap) {
                targetRelation = getTargetRelation(targetUserId);
                if (targetRelation == null) {
                    targetRelation = new UserSnowGardenVisitRelation(activityId, getUserId(), targetUserId);
                    relationMap.put(targetRelation.getTargetUserId(), targetRelation);
                }
            }
        }

        UserSnowGardenVisitRecord visitRecord = new UserSnowGardenVisitRecord(activityId, getUserId(), nowPeriod, targetUserId, visitType, objectId, addScore, needCrossBack ? 0 : 1, visitTime);
        if (visitType == eSnowGardenVisitType.VISIT_TYPE_VISITED_ME.getType()) {
            synchronized (helpMeRecordList) {
                helpMeRecordList.add(visitRecord);
                targetRelation.addHelpMeCount(nowPeriod, 1);

                while (helpMeRecordList.size() > 100) {
                    helpMeRecordList.remove(0);
                }
            }

        } else {
            synchronized (helpOtherRecordList) {
                helpOtherRecordList.add(visitRecord);
                targetRelation.addHelpHerCount(nowPeriod, 1);

                while (helpOtherRecordList.size() > 100) {
                    helpOtherRecordList.remove(0);
                }
            }
        }

        synchronized (needInsertHelpRecordList) {
            needInsertHelpRecordList.add(visitRecord);
        }

        return visitRecord;
    }

    public List<UserSnowGardenVisitRecord> getVisitRecordList(int recordType, int nowPeriod) {
        List<UserSnowGardenVisitRecord> list = new ArrayList<>();
        if (recordType == eSnowGardenVisitType.VISIT_TYPE_VISITED_ME.getType()) {
            synchronized (helpMeRecordList) {
                for (UserSnowGardenVisitRecord visitRecord : helpMeRecordList) {
                    if (visitRecord.getPeriod() == nowPeriod) {
                        list.add(visitRecord);
                    }
                }
            }

        } else {
            synchronized (helpOtherRecordList) {
                for (UserSnowGardenVisitRecord visitRecord : helpOtherRecordList) {
                    if (visitRecord.getPeriod() == nowPeriod) {
                        list.add(visitRecord);
                    }
                }
            }
        }
        list.sort((o1, o2) -> {
            return Long.compare(o2.getVisitTime(), o1.getVisitTime());
        });
        return list;
    }

    public void updateVisitRecordCrossBack(long targetUserId, long recordTime) {
        synchronized (helpOtherRecordList) {
            for (UserSnowGardenVisitRecord visitRecord : helpOtherRecordList) {
                if (visitRecord.getTargetUserId() == targetUserId && visitRecord.getVisitTime() == recordTime) {
                    visitRecord.setCrossBack(1);
                    synchronized (needInsertHelpRecordList) {
                        needInsertHelpRecordList.add(visitRecord);
                    }
                    break;
                }
            }
        }
    }

    /**
     * 请求拜访记录列表
     *
     * @param recordType
     * @return
     */
    public int getVisitRecordListMsg(int recordType,boolean isCrossReturn,Map<Long,UserBaseInfo> baseInfos) {
//        List<SnowGardenVisitorRecord> recordList = new ArrayList<>();
        long serverId = GameServer.getInstance().getServerId();
        SnowGardenConfig config = SnowGardenMgr.getSnowGardenConfig();
        if (config == null || !ActivityMgr.activityInTime(config.getActivityInfo())) {

            return GameErrorCode.E_ACTIVITY_HAD_END;
        }
        // 仅返回同阶段的访问数据
        int nowPeriod = SnowGardenMgr.calcNowPeriod();
//        if (getSnowGardenVisitorRecordData() != null) {
//            SnowGardenVisitorRecordData visitUserData = getSnowGardenVisitorRecordData().get(recordType);
//            for (SnowGardenVisitorRecord d : visitUserData.getRecordList()) {
//                if (d.getType() == nowPeriod) {
//                    recordList.add(d);
//                }
//            }
//            Comparator<SnowGardenVisitorRecord> com = Comparator.comparing(SnowGardenVisitorRecord::getTime);
//            // 按时间从大到小排序
//            recordList.sort(com.reversed());
//            int endIndex = pageSize * page > recordList.size()?recordList.size():pageSize * page;
//            // 如果起始点小于0或者起始点在结束点后面，返回空
//            if(pageSize * (page - 1) < 0 || pageSize * (page - 1) >= endIndex) {
//                recordList = new ArrayList<>();
//            } else {
//                recordList = recordList.subList(pageSize * (page - 1), endIndex);
//            }
//        }

        List<UserSnowGardenVisitRecord> visitRecordList = getVisitRecordList(recordType, nowPeriod);
        if (!isCrossReturn){
            List<Long> needCrossGetUserList = new ArrayList<>();
            for (UserSnowGardenVisitRecord visitRecord : visitRecordList) {
                long targetUserId = visitRecord.getTargetUserId();
                CrossUnionMember unionMember = CrossUnionMgr.getUnionMember(player.getUserInfo().getUnionUid(), targetUserId);
                if (unionMember == null) {
                    if (UserMgr.getUserBaseInfo(targetUserId,serverId) == null){
                        if (!needCrossGetUserList.contains(targetUserId)){
                            needCrossGetUserList.add(targetUserId);
                        }
                    }
                }
            }
            if (!needCrossGetUserList.isEmpty()){
                SnowGardenProto.SnowGardenGetQuitUserReqMsg.Builder builder =SnowGardenProto.SnowGardenGetQuitUserReqMsg.newBuilder();
                builder.setActivityId(config.getActivityInfo().getActivityId());
                builder.setType(recordType);
                builder.addAllUserId(needCrossGetUserList);
                player.sendPacket(CrossProtocol.C_SNOW_GARDEN_GET_QUIT_UNION_USER_VISIT_RECORD,builder);
                return 0;
            }
        }

        SnowGardenProto.SnowGardenVisitRecordListRespMsg.Builder builder = SnowGardenProto.SnowGardenVisitRecordListRespMsg.newBuilder();
        builder.setRet(0);
        builder.setPage(1);
        builder.setPageSize(visitRecordList.size());

        for (UserSnowGardenVisitRecord visitRecord : visitRecordList) {
            long targetUserId = visitRecord.getTargetUserId();
            UserBaseInfo userBaseInfo = null;
            CrossUnionMember unionMember = CrossUnionMgr.getUnionMember(player.getUserInfo().getUnionUid(),visitRecord.getTargetUserId());
            if (unionMember != null) {
                userBaseInfo = unionMember.getUserBaseInfo();
            }
            if (userBaseInfo == null){
                userBaseInfo = UserMgr.getUserBaseInfo(targetUserId,serverId);
            }

            if (userBaseInfo == null && isCrossReturn && baseInfos != null){
                if (baseInfos.containsKey(targetUserId)){
                    userBaseInfo = baseInfos.get(targetUserId);
                }
            }
            if (userBaseInfo == null){
                continue;
            }

            SnowGardenProto.SnowGardenVisitRecordDataMsg.Builder recordTemp = SnowGardenProto.SnowGardenVisitRecordDataMsg.newBuilder();
            recordTemp.setId(visitRecord.getObjectId());

            recordTemp.setUserData(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
            recordTemp.setScore(visitRecord.getAddScore());
            recordTemp.setType(recordType);
            recordTemp.setUserId(targetUserId);
            recordTemp.setTime((int) (visitRecord.getVisitTime() / 1000));

            builder.addVisitRecordList(recordTemp);
        }
//        for (SnowGardenVisitorRecord d : recordList) {
//            UserBaseInfo userBase = UserMgr.getUserBaseInfo(d.getUserId(), GameServer.getInstance().getServerId());
//            if (null != userBase) {
//                builder.addVisitRecordList(SnowGardenPb.parseSnowGardenVisitUserData(d, userBase));
//            }
//        }
        player.sendPacket(ClientProtocol.U_SNOW_GARDEN_GET_VISITOR_RECORD_LIST, builder);
        return 0;
    }

//    private SnowGardenVisitorRecordData initRecordData(long userId, int activityId, int type){
//        SnowGardenVisitorRecordData data = new SnowGardenVisitorRecordData();
//        data.setRecordList(new ArrayList<>());
//        data.setType(type);
//        data.setActivityId(activityId);
//        data.setUserId(userId);
//        return data;
//    }


    // 战令购买判断
    @Deprecated
    public void rechargeToken(int activityId, MallInfo mallInfo){
//        SnowGardenConfig snowGardenConfig = SnowGardenMgr.getSnowGardenConfig();
//        if (snowGardenConfig == null) {
//            return;
//        }
//        SnowGardenUserData snowGardenUserData = SnowGardenMgr.getSnowGardenUserDataNewIfNull(snowGardenConfig.getActivityInfo().getActivityId(), getUserId());
//        if (snowGardenUserData == null) {
//            return;
//        }
//        if (mallInfo.getShopType() == eShopType.ChineseChessSilverToken.getValue() || mallInfo.getShopType() == eShopType.ChineseChessGoldToken.getValue()) {
//            snowGardenUserData.setRecharge(true);
//            player.notifyListener(eGamePlayerEventType.CommonActivityFundProgress.getValue(), BigInteger.ZERO);
//        }
    }

    @Deprecated
    public boolean isBuyToken(MallInfo mallInfo) {
//        SnowGardenConfig snowGardenConfig = SnowGardenMgr.getSnowGardenConfig();
//        if (snowGardenConfig == null) {
//            return false;
//        }
//        SnowGardenUserData snowGardenUserData = SnowGardenMgr.getSnowGardenUserDataOnlyGet(snowGardenConfig.getActivityInfo().getActivityId(), getUserId());
//        if (snowGardenUserData == null) {
//            return false;
//        }
//        if (mallInfo.getShopType() == eShopType.SnowGardenMall.getValue()) {
//            return snowGardenUserData.isRecharge();
//        }
        return false;
    }

    // 活动礼包商店是否可以购买

    /**
     * 判断是否能充值
     */
    public boolean canBuy(int mallId) {
        // 获取活动数据
        SnowGardenConfig config = SnowGardenMgr.getSnowGardenConfig();
        if (config == null) {
            return false;
        }
        ActivityInfo activityInfo = config.getActivityInfo();
        if (!ActivityHelper.activityInShowTime(activityInfo)) {
            return false;
        }
        return true;
    }

    public UserSnowGardenVisitRelation getTargetRelation(long targetUserId) {
        UserSnowGardenVisitRelation visitRelation = relationMap.get(targetUserId);
        return visitRelation;
    }


    private SnowGardenCombTriggerData popCombTriggerData(SnowGardenUserData snowGardenUserData, int visitType, long userId) {
        List<SnowGardenCombTriggerData> combList = snowGardenUserData.getCombList();
        if (combList == null) {
            return null;
        }
        if (visitType == eSnowGardenRequestVisitType.BUILDING.getType()) {
            for (SnowGardenCombTriggerData data : combList) {
                if (data.getCombId() == eSnowGardenCombType.FIRST_PERIOD_COMB_FIVE.getId() && data.getParam().startsWith(String.valueOf(userId))) {
                    combList.remove(data);
                    return data;
                }
            }
        } else if (visitType == eSnowGardenRequestVisitType.INVITED.getType()) {
            for (SnowGardenCombTriggerData data : combList) {
                if (data.getCombId() == eSnowGardenCombType.SECOND_PERIOD_COMB_FOUR.getId() && data.getParam().startsWith(String.valueOf(userId))) {
                    combList.remove(data);
                    return data;
                }
            }
        }
        return null;
    }
}
